/*
*************************************************************************************
* File name: 
* Function: 
*
*************************************************************************************
*/

#ifndef _GLOBAL_H_
#define _GLOBAL_H_

#include <stdio.h>
#include "defines.h"
#include "context_ini.h"
#include "minmax.h"

#define _BUGFIX_NON16MUL_PICSIZE

/***********************************************************************
 * T y p e    d e f i n i t i o n s    f o r    T M L
 ***********************************************************************
 */

typedef unsigned char byte;    //!< byte type definition
#define pel_t byte
#define  snprintf _snprintf
byte *pic_buf;

//! Boolean Type
typedef enum {
	FALSE,
	TRUE
} Boolean;

//! definition of IVC syntax elements
typedef enum {
	SE_HEADER,
	SE_MBTYPE,
	SE_INTRAPREDMODE,
	SE_TUTYPE,
	SE_MVD,
	SE_CBP_INTRA,
	SE_LUM_DC_INTRA,
	SE_CHR_DC_INTRA,
	SE_LUM_AC_INTRA,
	SE_CHR_AC_INTRA,
	SE_CBP_INTER,
	SE_LUM_DC_INTER,
	SE_CHR_DC_INTER,
	SE_LUM_AC_INTER,
	SE_CHR_AC_INTER,
	SE_DELTA_QUANT_INTER,
	SE_DELTA_QUANT_INTRA,
	SE_BFRAME,
	SE_EOS,
	SE_MAX_ELEMENTS  //!< number of maximum syntax elements
} SE_type;         

typedef enum {
	BITS_HEADER,
	BITS_TOTAL_MB,
	BITS_MB_MODE,
	BITS_INTER_MB,
	BITS_CBP_MB,
	BITS_COEFF_Y_MB,
	BITS_COEFF_UV_MB,
	BITS_DELTA_QUANT_MB,
	MAX_BITCOUNTER_MB
} BitCountType;

typedef struct BbvBuffer_t
{
	char  bbv_mode;           // 0:not 0xFFFF, 1:0xFFFF
	char  vec_flag;           // the flag of video edit code(vec), 0: vec doesn't exit, 1: vec exit.
	int   bitrate;            // bit per second (bit/s)
	float framerate;          // frame per second (frame/s)
	float bbv_delay;
	float low_delay;
	int   BBS_size;
	float frmout_interval;
	int   currFrm_max_bit;
	int   currFrm_min_bit;
	int   frm_no;
	int   check_continue;
	int   *FrameBits;
} BbvBuffer_t;

//! Macroblock
typedef struct macroblock
{
	int                 currSEnr;                   //!< number of current syntax element
	int                 slice_nr;
	int                 delta_qp;
	int                 qp;
	int                 bitcounter[MAX_BITCOUNTER_MB];
	struct macroblock   *mb_available[3][3];        /*!< pointer to neighboring MBs in a 3x3 window of current MB, which is located at [1][1] \n
														 NULL pointer identifies neighboring MBs which are unavailable */
	// some storage of macroblock syntax elements for global access
	int                 mb_type;
	int                 trans_type;
	int                 trans_split[4];
	int                 mvd[2][BLOCK_MULTIPLE][BLOCK_MULTIPLE][2];          //!< indices correspond to [forw,backw][block_y][block_x][x,y]
	int                 intra_pred_modes[16];
	int                 cbp;
	int                 b8mode[4];
	int                 b8pdir[4];
	unsigned long       cbp_bits;
	int                 fw_ref[4];
	int                 lf_disable;
	int                 c_ipred_mode;      //!< chroma intra prediction mode
	int                 IntraChromaPredModeFlag;

	struct macroblock   *mb_available_up;   //!< pointer to neighboring MB (AEC)
	struct macroblock   *mb_available_left; //!< pointer to neighboring MB (AEC)
	int mbAddrA, mbAddrB, mbAddrC, mbAddrD;
	int mbAvailA, mbAvailB, mbAvailC, mbAvailD;
	int skip_flag;

	int slice_header_flag;
	int sliceqp;
} Macroblock;

//! Bitstream
typedef struct
{
	int             byte_pos;           //!< current position in bitstream;
	int             bits_to_go;         //!< current bitcounter
	byte            byte_buf;           //!< current buffer for last written byte
	int             stored_byte_pos;    //!< storage for position in bitstream;
	int             stored_bits_to_go;  //!< storage for bitcounter
	byte            stored_byte_buf;    //!< storage for buffer of last written byte

	byte            byte_buf_skip;      //!< current buffer for last written byte
	int             byte_pos_skip;      //!< storage for position in bitstream;
	int             bits_to_go_skip;    //!< storage for bitcounter

	byte            *streamBuffer;      //!< actual buffer for written bytes
	int             write_flag;         //!< Bitstream contains data and needs to be written

} Bitstream;
Bitstream *currBitStream;

#define MAXSLICEPERPICTURE 100


typedef struct{
	int extension_id;
	int copyright_flag;
	int copyright_id;
	int original_or_copy;
	int reserved;
	int copyright_number;
} CopyRight;

typedef struct{
	int reserved;
	int camera_id;
	int height_of_image_device;
	int focal_length;
	int f_number;
	int vertical_angle_of_view;
	int camera_position_x;
	int camera_position_y;
	int camera_position_z;
	int camera_direction_x;
	int camera_direction_y;
	int camera_direction_z;
	int image_plane_vertical_x;
	int image_plane_vertical_y;
	int image_plane_vertical_z;
} CameraParamters;

extern CopyRight *cp;
extern CameraParamters *camera;


byte   *imgY_org_buffer;           //!< Reference luma image

#ifdef TDRDO
byte * imgY_pre_buffer;
#endif 

// global picture format dependend buffers, mem allocation in image.c

uchar_t *imgY_org_frm;
uchar_t *imgU_org_frm;
uchar_t *imgV_org_frm;

int   ***tmp_mv_frm;             //!< motion vector buffer
int    **refFrArr_frm;           //!< Array for reference frames of each block

uchar_t *imgY;
uchar_t *imgU;
uchar_t *imgV;

uchar_t *imgY_org;           //!< Reference luma image
uchar_t *imgU_org;          //!< Reference croma image
uchar_t *imgV_org;          //!< Reference croma image

int    *img4Y_tmp;          //!< for quarter pel interpolation
//uchar_t    *img4Y_tmp;          //!< for quarter pel interpolation
int   ***tmp_mv;             //!< motion vector buffer

int    **refFrArr;           //!< Array for reference frames of each block

int Min_V_MV;
int Max_V_MV;
int Min_H_MV;
int Max_H_MV;

uchar_t *mref[33];                    //!< 1/4 pix luma
uchar_t *mcef[33][2];                 //!< pix chroma

uchar_t *reference_frame[33][3];      //[refnum][yuv][height*width]
uchar_t *current_frame[3];    //[yuv][height*width]

pel_t *Refbuf11[33];                //!< 1/1th pel (full pel) reference frame buffer

uchar_t *ref_frm[33][3];  //[refnum(4 for filed)][yuv][height(height/2)*width]

// global picture format dependend buffers, mem allocation in image.c (frame buffer)
uchar_t  *mref_frm[33];               //!< 1/4 pix luma //[2:ref_index]

int af_intra_cnt;

// reference frame buffer

unsigned char **reference_field[6][3];  //[refnum][yuv][height/2][width]
unsigned char ***ref[4];  //[refnum(4 for filed)][yuv][height(height/2)][width]
unsigned char ***b_ref[2],***f_ref[2];
unsigned char ***b_ref_frm[2], ***f_ref_frm[2];

// B pictures
// motion vector : forward, backward, direct
int  ***tmp_fwMV;
int  ***tmp_bwMV;


int  ***dfMV;
int  ***dbMV;
int   **fw_refFrArr;
int   **bw_refFrArr;
byte  **nextP_imgY;
byte ***nextP_imgUV;
//pel_t *Refbuf11[4];            //!< 1/1th pel (full pel) reference frame buffer



// global picture format dependend buffers, mem allocation in image.c (frame buffer)
//byte  **mref_frm[2];               //!< 1/4 pix luma //[2:ref_index]
// B pictures

int   **fwdir_refFrArr;         //!< direct mode forward reference buffer
int   **bwdir_refFrArr;         //!< direct mode backward reference buffer

// global picture format dependend buffers, mem allocation in image.c (frame buffer)

int    **refFrArr_frm;           //!< Array for reference frames of each block
int   direct_mode;

// B pictures
// motion vector : forward, backward, direct
int   **fw_refFrArr_frm;
int   **bw_refFrArr_frm;

int intras;         //!< Counts the intra updates in each frame.

int  Bframe_ctr, frame_no, nextP_tr_frm,nextP_tr;
int  tot_time;
int  temp_vecperiod;
       
#define ET_SIZE 300      //!< size of error text buffer
char errortext[ET_SIZE]; //!< buffer for error message for exit with error()

//! SNRParameters
typedef struct
{
	float snr_y;               //!< current Y SNR
	float snr_u;               //!< current U SNR
	float snr_v;               //!< current V SNR
	float snr_y1;              //!< SNR Y(dB) first frame
	float snr_u1;              //!< SNR U(dB) first frame
	float snr_v1;              //!< SNR V(dB) first frame
	float snr_ya;              //!< Average SNR Y(dB) remaining frames
	float snr_ua;              //!< Average SNR U(dB) remaining frames
	float snr_va;              //!< Average SNR V(dB) remaining frames
} SNRParameters;

                             //! all input parameters
typedef struct
{
	int no_frames;                //!< number of frames to be encoded
	int qp0;                      //!< QP of first frame
	int qpN;                      //!< QP of remaining frames
	int jumpd;                    //!< number of frames to skip in input sequence (e.g 2 takes frame 0,3,6,9...)
	int hadamard;                 /*!< 0: 'normal' SAD in 1/3 pixel search.  1: use 4x4 Haphazard transform and '
									   Sum of absolute transform difference' in 1/3 pixel search                   */
	int usefme;                   //!< Fast Motion Estimat. 0=disable, 1=UMHexagonS
	int search_range;             /*!< search range - integer pel search and 16x16 blocks.  The search window is
									   generally around the predicted vector. Max vector is 2xmcrange.  For 8x8
									   and 4x4 block sizes the search range is 1/2 of that for 16x16 blocks.       */
	int no_multpred;              /*!< 1: prediction from the last frame only. 2: prediction from the last or
									   second last frame etc.  Maximum 5 frames                                    */
	int img_width;                //!< GH: if CUSTOM image format is chosen, use this size
	int img_height;               //!< GH: width and height must be a multiple of 16 pels
	int yuv_format;               //!< GH: YUV format (0=4:0:0, 1=4:2:0, 2=4:2:2, 3=4:4:4,currently only 4:2:0 is supported)
	int color_depth;              //!< GH: YUV color depth per component in bit/pel (currently only 8 bit/pel is supported)
	int intra_upd;                /*!< For error robustness. 0: no special action. 1: One GOB/frame is intra coded
									   as regular 'update'. 2: One GOB every 2 frames is intra coded etc.
									   In connection with this intra update, restrictions is put on motion vectors
									   to prevent errors to propagate from the past                                */
	int blc_size[8][2];           //!< array for different block sizes
	int  infile_header;           //!< If input file has a header set this to the length of the header
	char infile[1000];             //!< YUV 4:2:0 input format
	char outfile[1000];            //!< IVC compressed output bitstream  
	char ReconFile[1000];          //!< Reconstructed Pictures
	char TraceFile[1000];          //!< Trace Outputs
	int intra_period;

	// B pictures
	int successive_Bframe;        //!< number of B frames that will be used
	int qpB;                      //!< QP of B frames
	int SequenceHeaderType;

	int InterSearch16x16;
	int InterSearch8x8;
	int InterSearch16x8;
	int InterSearch8x16;

	int loop_filter_disable;
	int Alpha, Beta;

	char PictureTypeSequence[MAXPICTURETYPESEQUENCELEN];

	int rdopt;

	//IVC
	int aspect_ratio_information;
	int frame_rate_code;
	//int bit_rate;
	int bit_rate_lower;
	int bit_rate_upper;

	int vec_period;
	int seqheader_period;	// Random Access period though sequence header

	int bbv_buffer_size;
	int video_format;
	int color_description;
	int color_primaries;
	int transfer_characteristics;
	int matrix_coefficients;
	int hour;
	int minute;
	int second;
	int frame_offset;
	int profile_id;
	int level_id;
	int low_delay;
	int chroma_format;
	int yuv_structure;
	int sample_precision;
	int video_range;
	int stream_length_flag;
	int fixed_picture_qp;
	int time_code_flag;
	int display_horizontal_size;
	int display_vertical_size;
	int slice_parameter;
	int slice_row_nr;
	int output_enc_pic;  //output_enc_pic
	//! Rate Control on IVC standard 
	int RCEnable;
	int bit_rate;
	int SeinitialQP;
	int basicunit;
	int channel_type;
	int frame_rate;
	int stuff_height;
	int symbol_mode;              //!< Specifies the mode the symbols are mapped on bits

#ifdef TDRDO
	int TRDOLength;
#endif

	int  BBS_size;
	char bbv_mode;

	int p_sub_type_coding;
	int p_sub_type_delta0;
	int p_sub_type_delta1;
	int p_sub_non_type_coding;    // non-adaptive non-reference P frame coding 
	int rdo_q_flag;
	int multiple_hp_flag;
	int abt_enable;
	int if_type;

	int number_reference_frame;

	int chroma_enhanncement;

} InputParameters;


                                //!< statistics
typedef struct
{
	int   quant0;                 //!< quant for the first frame
	int   quant1;                 //!< average quant for the remaining frames
	float bitr;                   //!< bit rate for current frame, used only for output til terminal
	float bitr0;                  //!< stored bit rate for the first frame
	float bitrate;                //!< average bit rate for the sequence except first frame
	int   bit_ctr;                //!< counter for bit usage
	int   bit_ctr_0;              //!< stored bit use for the first frame
	int   bit_ctr_n;              //!< bit usage for the current frame
	int   bit_slice;              //!< number of bits in current slice
	int   bit_use_mode_inter[2][MAXMODE]; //!< statistics of bit usage
	int   bit_ctr_emulationprevention; //!< stored bits needed to prevent start code emulation
	int   mode_use_intra[25];     //!< Macroblock mode usage for Intra frames
	int   mode_use_inter[2][MAXMODE];

	int   mb_use_mode[2];

	// B pictures
	int   *mode_use_Bframe;
	int   *bit_use_mode_Bframe;
	int   bit_ctr_P;
	int   bit_ctr_B;
	float bitrate_P;
	float bitrate_B;

#define NUM_PIC_TYPE 5
	int   bit_use_stuffingBits[NUM_PIC_TYPE];
	int   bit_use_mb_type[NUM_PIC_TYPE];
	int   bit_use_header[NUM_PIC_TYPE];
	int   tmp_bit_use_cbp[NUM_PIC_TYPE];
	int   bit_use_coeffY[NUM_PIC_TYPE];
	int   bit_use_coeffC[NUM_PIC_TYPE];
	int   bit_use_delta_quant[NUM_PIC_TYPE];

	int   em_prev_bits_frm;
	int   em_prev_bits_fld;
	int  *em_prev_bits;
	int   bit_ctr_parametersets;
} StatParameters;


extern InputParameters *input;
extern StatParameters *stat;
extern SNRParameters *snr;


int mv_out_of_range;

int picture_distance;		

// files
FILE *p_stat;                    //!< status file for the last encoding session
FILE *p_log;                     //!< SNR file

int p_dec,p_dec_u,p_dec_v;   //!< internal decoded image for debugging
int p_in;                      //!< YUV

FILE *p_datpart;                 //!< file to write bitlength and id of all partitions
FILE *p_trace;                   //!< Trace file

int  sign(int a,int b);
void init_img();
void report();
void information_init();

void  LumaPrediction8x8 (int,int, int, int, int, int, int);

int   SATD (int*, int);

pel_t* FastLineX (int, pel_t*, int, int);
pel_t* UMVLineX  (int, pel_t*, int, int);

#ifdef RDO_Q
void LumaResidualCoding (double);
void ChromaResidualCoding (int*, double);
#else
void LumaResidualCoding ();
void ChromaResidualCoding (int*);
#endif

void IntraChromaPrediction8x8 (int*, int*, int*);
int  writeMBHeader   (int rdopt); 

extern int*   refbits;
extern int*** motion_cost;

int scale_motion_vector(int motion_vector, int currblkref, int neighbourblkref, int ref);

int calculate_distance(int blkref, int fw_bw ); 
void  PartitionMotionSearch     (int, int, double);

void MHMC_PartitionMotionSearch (int, int, double);

void  PartitionMotionSearch_bid (int, int, double);
#ifdef RDO_Q
int   LumaResidualCoding8x8     (int*,int, int, int, int, int, double);
#else
int   LumaResidualCoding8x8     (int*, int, int, int, int, int);
#endif
int   writeLumaCoeff8x8         (int, int, int);
int   writeMotionVector8x8      (int, int, int, int, int, int, int, int);
int   MHMC_writeMotionVector8x8      (int, int, int, int, int, int, int, int);

int   writeChromaIntraPredMode  ();

int		Get_Direct_Cost8x8 (int, double);
int		Get_Direct_CostMB  (double);
int		B8Mode2Value (int b8mode, int b8pdir);
int		GetSkipCostMB (double lambda);
void	FindSkipModeMotionVector ();


// dynamic mem allocation
int  init_global_buffers();
void free_global_buffers();
void no_mem_exit  (char *where);

int  get_mem_mv  (int******);
void free_mem_mv (int*****);
void free_img    ();

#define COF_SIZE_ALL (17 * 4 * 6 * 2)
#define COF_SIZE_LUMA (17 * 4 * 4)

int  get_mem_ACcoeff  (int* cofAC[6][4][2]);
void free_mem_ACcoeff(int* cofAC[6][4][2]);

int  writeBlockCoeff (int block8x8);
int  storeMotionInfo (int pos);

void intrapred_luma_IVC(int img_x,int img_y, int block_size);


void  encode_one_macroblock();
void  start_macroblock();
void  set_MB_parameters (int mb);           //! sets up img-> according to input-> and currSlice->

void  terminate_macroblock(Boolean *end_of_picture);
void  write_one_macroblock(int eos_bit);
void  proceed2nextMacroblock();

void  CheckAvailabilityOfNeighbors();

void error(char *text, int code);
int  start_sequence();
int  terminate_sequence();
int  start_slice();

void stuffing_byte(int n);


//============= rate-distortion optimization ===================
void  clear_rdopt      ();
void  init_rdopt       ();

void SetImgType();

#define IMG_NUMBER (img->number)

extern int*** motion_cost_bid;
int   ipdirect_x,ipdirect_y;
void  Get_IP_direct();
void ForwardPred ( int *fw_mcost,int* best_fw_ref, int *best_bw_ref, int max_ref, int adjust_ref, int mode, int block,  double lambda_motion, int write_ref, int lambda_motion_factor);
void MHMC_ForwardPred ( int *p_bid_mcost,int* best_fw_ref, int *best_bw_ref, int max_ref, int adjust_ref, int mode, int block,  double lambda_motion, int write_ref, int lambda_motion_factor);
void BiPred ( int *best_bw_ref, int *bw_mcost, int *bid_mcost, int* bid_best_fw_ref, int* bid_best_bw_ref,int mode, int block, double lambda_motion,int max_ref, int adjust_ref );
void FreeBitstream();
void AllocateBitstream();
/*!*******************************************************AEC  by ZL**********************************!*/
typedef enum {
  UVLC,
  AEC
} SymbolMode;

/***********************************************************************
 * D a t a    t y p e s   f o r  C A B A C
 ************************************************************************/

//! struct to characterize the state of the arithmetic coding engine
typedef struct
{
	unsigned int  Elow;
	unsigned int	E_s1;
	unsigned int  E_t1;
	unsigned char  Ebuffer;
	unsigned int  Ebits_to_go;
	unsigned int  Ebits_to_follow;
	byte          *Ecodestrm;
	int           *Ecodestrm_len;
	//  int           *Ecodestrm_laststartcode;
	// storage in case of recode MB
	unsigned int  ElowS, ErangeS;
	unsigned int  EbufferS;
	unsigned int  Ebits_to_goS;
	unsigned int  Ebits_to_followS;
	byte          *EcodestrmS;
	int           *Ecodestrm_lenS;
	int           C, CS;
	int           E, ES;
	int           B, BS;
} EncodingEnvironment;

typedef EncodingEnvironment *EncodingEnvironmentPtr;
//! struct for context management
typedef struct
{
	unsigned char	MPS;   //1 bit
	unsigned int	LG_PMPS; //10 bits	
	unsigned char	cycno;	//2 bits	
} BiContextType;
typedef BiContextType *BiContextTypePtr;
/**********************************************************************
 * C O N T E X T S   F O R   T M L   S Y N T A X   E L E M E N T S
 **********************************************************************
 */
#define NUM_MB_TYPE_CTX  11
#define NUM_B8_TYPE_CTX  9
#define NUM_MV_RES_CTX   10

#define NUM_DELTA_QP_CTX 4



typedef struct
{
	BiContextType mb_type_contexts [3][NUM_MB_TYPE_CTX];
	BiContextType b8_type_contexts [2][NUM_B8_TYPE_CTX];
	BiContextType mv_res_contexts  [2][NUM_MV_RES_CTX];
	BiContextType delta_qp_contexts   [NUM_DELTA_QP_CTX];
} MotionInfoContexts;

#define NUM_CBP_CTX    4
#define NUM_MAP_CTX   20
#define NUM_LAST_CTX  20
#define NUM_ONE_CTX    5
#define NUM_ABS_CTX    5
#define NUM_IPR_CTX    4
#define NUM_CIPR_CTX   4

typedef struct
{
	BiContextType qsplit_contexts[1];
	BiContextType  ipr_contexts[NUM_IPR_CTX];
	BiContextType  cipr_contexts[NUM_CIPR_CTX];
	BiContextType  cbp_contexts[3][NUM_CBP_CTX];
	BiContextType  one_contexts[NUM_BLOCK_TYPES][NUM_ONE_CTX];
	BiContextType  abs_contexts[NUM_BLOCK_TYPES][NUM_ABS_CTX];
	BiContextType  map_contexts[NUM_BLOCK_TYPES][NUM_MAP_CTX];
	BiContextType  last_contexts[NUM_BLOCK_TYPES][NUM_LAST_CTX];
	BiContextType  tu_size_context[1];
} TextureInfoContexts;

//! Syntaxelement
typedef struct syntaxelement
{
	int                 type;           //!< type of syntax element for data part.
	int                 value1;         //!< numerical value of syntax element
	int                 value2;         //!< for blocked symbols, e.g. run/level
	int                 len;            //!< length of code
	int                 inf;            //!< info part of UVLC code
	unsigned int        bitpattern;     //!< UVLC bitpattern
	int                 context;        //!< AEC context
	int                 k;              //!< AEC context for coeff_count,uv
	int                 golomb_grad;    //needed if type is a golomb element (IVC)
	int                 golomb_maxlevels; // if this is zero, do not use the golomb coding. (IVC)

#if TRACE
#define             TRACESTRING_SIZE 100            //!< size of trace string
	char                tracestring[TRACESTRING_SIZE];  //!< trace string
#endif

	//!< for mapping of syntaxElement to UVLC
	void(*mapping)(int value1, int value2, int* len_ptr, int* info_ptr);

	//!< edit start for mapping of syntaxElement to UVLC
	void(*writing)(struct syntaxelement *, EncodingEnvironmentPtr); //added by lzhang 
	//!< edit end for mapping of syntaxElement to UVLC

} SyntaxElement;
SyntaxElement   MB_SyntaxElements[MAX_SYMBOLS_PER_MB];    //!< temporal storage for all chosen syntax elements of one MB

//! DataPartition
typedef struct datapartition
{
	Bitstream           *bitstream;
	EncodingEnvironment ee_AEC;
	int(*writeSyntaxElement)(SyntaxElement *, struct datapartition *);
} DataPartition;

//! Slice
typedef struct
{
	int                 picture_id;
	int                 qp;
	int                 picture_type; //!< picture type
	int                 start_mb_nr;
	int                 num_mb;       //!< number of MBs in the slice
	DataPartition       *partArr;     //!< array of partitions
	MotionInfoContexts  *mot_ctx;     //!< pointer to struct of context models for use in AEC
	TextureInfoContexts *tex_ctx;     //!< pointer to struct of context models for use in AEC
} Slice;

typedef struct pix_pos
{
	int available;   //ABCD
	int mb_addr;    //MB position
	int x;
	int y;
	int pos_x;     //4x4 x-pos
	int pos_y;
} PixelPos;

typedef struct 
{
	int   no_slices;
	int   bits_per_picture;
	float distortion_y;
	float distortion_u;
	float distortion_v;
	//!EDIT START <added by  AEC
	Slice *slices[MAXSLICEPERPICTURE];
	//!EDIT end <added by  AEC
} Picture;

Picture *frame_pic;

Picture *malloc_picture();
#if TRACE
void  trace2out(SyntaxElement *se);
#endif

//! ImageParameters
typedef struct
{
	int number;                  //!< current image number to be encoded
	int nb_references;
	int current_mb_nr;
	int total_number_mb;
	int current_slice_nr;
	int type;
	int no_multpred;             /*!< 1: prediction from the last frame only.
								 2: prediction from the last or second last frame etc. */
	int qp;                      //!< quant for the current frame
	int framerate;

	int width;                   //!< Number of pels
	int width_cr;                //!< Number of pels chroma
	int height;                  //!< Number of lines
	int height_cr;               //!< Number of lines  chroma
	int iStride;
	int iStrideC;
	int mb_y;                    //!< current MB vertical
	int mb_x;                    //!< current MB horizontal
	int block_y;                 //!< current block vertical
	int block_x;                 //!< current block horizontal
	int pix_y;                   //!< current pixel vertical
	int pix_x;                   //!< current pixel horizontal
	int pix_c_y;                 //!< current pixel chroma vertical
	int block_c_x;               //!< current block chroma vertical
	int pix_c_x;                 //!< current pixel chroma horizontal
	int cod_counter;             //!< Current count of number of skipped macroblocks in a row

	// some temporal buffers
	uchar_t mprr[NO_INTRA_PMODE][256];         //!< all 9 prediction modes? // enlarged from 4 to 16 for ABT (is that neccessary?)
	int mprr_flag[NO_INTRA_PMODE][1];

	uchar_t mprr_c[2][4][8*16];      //!< new chroma 8x8 intra prediction modes, 
	int***** mv;                 //!< motion vectors predictors for all block types and all reference frames
	int mpr[16][16];             //!< current best prediction mode
	int m7[16][16];              //!< the diff pixel values between orginal image and prediction

	int *cofAC[6][4][2];               //!< AC coefficients [8x8block][4x4block][level/run][scan_pos]

	Macroblock    *mb_data;                                   //!< array containing all MBs of a whole frame
	SyntaxElement   *MB_SyntaxElements; //!< by oliver 0612
	int *quad;               //!< Array containing square values,used for snr computation  */                                         /* Values are limited to 5000 for pixel differences over 70 (sqr(5000)).
	int **intra_block;

	int tr;
	int direct_intraP_ref[4][4];
	int imgtr_next_P_frm;
	int imgtr_last_P_frm;
	int imgtr_next_P_fld;
	int imgtr_last_P_fld;
	int imgtr_last_prev_P_frm;
	// B pictures
	int b_interval;
	int p_interval;
	int b_frame_to_code;
	int fw_mb_mode;
	int bw_mb_mode;
	int***** p_fwMV;       //!<forward MV predictors,  for MVDFW
	int***** p_bwMV;       //!< backward MV predictors, for MVDBW

	int***** all_mv;       //!< replaces local all_mv, all_mv[block_x][block_y][refframe][blocktype][0/1]
	int***** all_bimv;     //!< replaces local all_mv, all_mv[block_x][block_y][refframe][blocktype][0/1] is used for multi-hypothesis mc of p frame
	int***** bimv;         //!< motion vector predictors for multi-hypothesis mc of p frame
	int***** all_Lbimv;
	int***** Lbimv;
	int***** all_bmv;      //!< replaces local all_mv

	int mv_range_flag;

	int auto_crop_right;
	int auto_crop_bottom;
	int buf_cycle;

	//the following are sent in the slice header
	int NoResidueDirect;

	int coding_stage;
	int block8_x;
	int block8_y;
	int coded_mb_nr;


	int***** omv;
	int***** all_omv;       //!< replaces local all_mv

	int current_slice_start_mb;
	int progressive_frame;
	int dropflag;
	int current_mb_nr_fld;

	int mb_no_currSliceLastMB; // the last MB no in current slice.   


	int Seqheader_flag;
	int EncodeEnd_flag;
	int curr_picture_distance;
	int last_picture_distance;
	int count;

	int p_sub_type_start;
	double tag_hp;
	int typeb;

	int level_SUM_bit;
	int level_fourframe_bit;
	int SUM_bit;
	int Mean_bit;
	int fourframe_bit;
	int p_one_bit;
	int p_three_bit;
	int p_sub_bits;
	int level_p_sub_bits;

	/*! EDIT START For AEC  ****************************!*/
	int model_number;
	Slice *currentSlice;                         //!< pointer to current Slice data struct
	int	  subblock_x;
	int	  subblock_y;
	int	  is_v_block;
	int	  is_intra_block;
	int   PicWidthInMbs;
	int   PicHeightInMbs;
	int   PicSizeInMbs;
	/*! EDIT END For AEC   ****************************!*/

	unsigned short bbv_delay;

} ImageParameters;

extern ImageParameters *img;

Bitstream *tmpStream;  
int current_slice_bytepos;


int intra_frame_number;
int *****all_mincost;//store the MV and SAD information needed;

// loopfilter
void DeblockMb(ImageParameters *img,
			   uchar_t *imgY,
			   uchar_t *imgU,
			   uchar_t *imgV,
			   int blk_y,
			   int blk_x,
			   int current_mb_nr_temp);
void DeblockFrame(ImageParameters *img, byte *imgY, byte *imgU, byte *imgV);

// Added for (re-) structuring the RM09 soft
void free_picture (Picture *pic);
int	 encode_one_slice(Picture *pic);   //! returns the number of MBs in the slice
void free_slice_list(Picture *currPic);

void AllocatetmpBitstream();
void FreetmpBitstream();
void Demulate(Bitstream *currStream, int current_slice_bytepos);

void SetModesAndRefframeForBlocks (int mode);

void SetModesAndRefframe (int b8, int* fw_mode, int* bw_mode, int* fw_ref, int* bw_ref);

int  writeLumaCoeff8x8_AEC( int b8, int b4, int intra8x8mode, int bsize) ;
int  writeChromaCoeff8x8_AEC ( int b8 );
int  terminate_slice();
void getNeighbour(int curr_mb_nr, int xN, int yN, int luma, PixelPos *pix); 
void get_mb_pos (int mb_addr, int *x, int*y);
void getLuma8x8Neighbour (int curr_mb_nr, int b8_x, int b8_y, int rel_x, int rel_y, PixelPos *pix);
void free_slice();
int  AEC_writting;
#define MAX_REGION_NUM	100

int I_P_num;

int  seq_header; 
int  slice_header[3]; 
#endif
